import static org.junit.Assert.*;

import org.junit.*;

/**
 * VendingMachineItemTest is used to test VendingMachineItem.java 
 * using JUnit 4.0 specifically:
 * 1- VendingMachineItem constructor.
 * 2- getName method.
 * 3- getPrice method.
 * @author Mohammed Alghareeb
 */
public class VendingMachineItemTest {

//This exception is throw in testVendingMachineItem
	/** The vend exception. */
static VendingMachineException vendException = new VendingMachineException();
	
	/**
	 * setUpClass() runs once at the beginning of the test.
	 */
	@BeforeClass public static void setUpClass () 
	{
		System.out.println("\t\t *Commencing VendingMachineItem unite testing*");
		VendingMachineTest.printChar('=', 70);
	}

	/**
	 * setUp() runs before each unit test.
	 */
	@Before public void setUp()
	{
		System.out.println("= Preparing Next test");
		VendingMachineTest.printChar('=',70);
	}
	
	/**
	 * testVendingMachineItemConstructor() tests VendingMachineItem constructor.
	 */
	@Test public void testVendingMachineItemConstructor()
	{
		System.out.println("Step 1 - testVendingMachineItemConstructor();");
		System.out.println("testVendingMachineItemConstructor() started ");
		//Testing the construct with correct vals
		constructTestWithCorrectVals();
		//Testing the construct with wrong vals
		constructTestWithIllegalVals();
		System.out.println("= testVendingMachineItemConstructor ended successfull");
	}

	
	/**
	 * testGetName tests the ability to retrieve the item's name.
	 */
	@Test public void testGetName()
	{
		System.out.println("Step 2 - testGetName();");
		System.out.println("testGetName() started ");
		String expectedName = "Snicker Bar";
		String itemName = item.getName();
		assertEquals(expectedName, itemName);
		System.out.println("testGetName() ended successfully");
	}

	/**
	 * testGetPrice tests the ability to retrieve the item's price.
	 */
	@Test public void testGetPrice()
	{
		System.out.println("Step 3 - testGetPrice();");
		System.out.println("testGetPrice() started ");
		double expectedPrice = 1.75;
		double itemPrice = item.getPrice();
		assertEquals(expectedPrice, itemPrice, 0.0001);
		System.out.println("testGetPrice() ended successfully");
	}
	
	/**
	 * After() runs after each test. 
	 */
	@After public void tearDown()
	{		
		System.out.println("@Test completed and passed successfully");
		VendingMachineTest.printChar('=',70);
	}
	
	/**
	 * AfterClass() runs once at the end of all the tests.
	 */
	@AfterClass public static void tearDownClass()
	{
		System.out.println("\t\t *VendingMachineItem tests passed successfully*");
		VendingMachineTest.printChar('=',70);
	}

	
	
	
	/**
	 * This method is used in testVendingMachineItem
	 * it passes wrong or illegal parameters to VendingMachineItem 
	 * and it expect the process to fail.
	 */
	private static void constructTestWithIllegalVals() {
		Throwable caught = null;
		
		try{
			System.out.println("Phase2: Creating Obj using the wrong value passed to the constructor");
		      new VendingMachineItem("Kitkat",-1.0);
		      
		}catch(VendingMachineException exp){
			caught = exp;
			System.out.println(exp.getMessage());
		}
		assertNotNull(caught);
		assertSame(VendingMachineException.class, caught.getClass());
		
		System.out.println("Phase2: Completed and passed successfully");
	}

	/**
	 * This method is used in testVendingMachineItem
	 * it passes correct values to VendingMachineItem 
	 * and it expect the process to succeed. 
	 */
	private static void constructTestWithCorrectVals() {
		
	
			new VendingMachineItem ("Snicker Bar", 1.75);
			new VendingMachineItem ("Pepsi", 1.25);
			new VendingMachineItem ("Kitkat", 1.25);
			System.out.println("Phase1: Creating VendingMachineItem Objects with correct value passed to the constructor");
			System.out.println("Phase1: Completed and passed successfully");
	}
	//Once we passed BeforeClass we can create Objs because the construct is working properly
	// item is the Obj sheared between all test cased 
	/** The item. */
	VendingMachineItem item =  new VendingMachineItem ("Snicker Bar", 1.75);
	
}
